﻿using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Component.Tools;
using Component.Track;
using Component.UI;
using Tools;
using UnityEngine;
using Random = System.Random;

namespace Component.Passenger
{
    
    public class PassengerGeneration
    {
        class Nested
        {
            static Nested()
            {
            }

            internal static readonly PassengerGeneration pg = new PassengerGeneration();
        }
        
        public static PassengerGeneration Instance => Nested.pg;

        private readonly Task generationTask;

        /// <summary>
        /// 乘客与站点的关系
        /// </summary>
        private readonly Dictionary<int, List<PassengerNode>> passengers;
        public delegate void PassengerGenerate(int parent, Transform child);

        public PassengerGenerate OnGenerating
        {
            get;
            set;
        }
        
        public PassengerGeneration()
        {
            passengers = new Dictionary<int, List<PassengerNode>>();
        }

        public List<PassengerNode> GetPassengers(int parentId)
        {
            if (!passengers.ContainsKey(parentId))
            {
                return null;
            }
            return passengers[parentId];
        }

        public void PauseGeneration()
        {
            generationTask.Pause();
        }

        public void Continue()
        {
            generationTask.Continue();
        }

        public void ClearAll(int stationId)
        {
            if (passengers.ContainsKey(stationId))
            {
                foreach (var passenger in passengers[stationId])
                {
                    ResetPassenger(passenger);
                }
            }
        }
        
        public void Generate(Transform parent, int parentId)
        {
            
            if (!passengers.ContainsKey(parentId))
            {
                passengers.Add(parentId, new List<PassengerNode>());
            }

            DrawMeshTools.MeshType type;
            try
            {
                type = TransferTools.RandomMeshType(StationGeneration.Instance.GetStationType(parentId));
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                return;
            }
            PassengerNode node = PassengerManager.CreatePassenger();
            node.Type = type;
            node.transform.parent = parent;
            passengers[parentId].Add(node);
            
        }
        
        public void Generate(Transform parent, int parentId, DrawMeshTools.MeshType type)
        {
            
            if (!passengers.ContainsKey(parentId))
            {
                passengers.Add(parentId, new List<PassengerNode>());
            }
            
            PassengerNode node = PassengerManager.CreatePassenger();
            node.Type = type;
            node.transform.parent = parent;
            passengers[parentId].Add(node);
        }

        public IEnumerator GetOff(int parentId,  int stationId)
        {
            if (!passengers.Keys.Contains(parentId))
            {
                yield break;
            }
            List<PassengerNode> list = passengers[parentId];
            DrawMeshTools.MeshType stationType = StationGeneration.Instance.GetStationType(stationId);
            
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].Type == stationType)
                {
                    ResetPassenger(list[i]);
                    list.RemoveAt(i);
                }
                yield return new WaitForSeconds(.2f);
            }
        }

        public static void ResetPassenger(PassengerNode passenger)
        {
            PassengerManager.ResetPassenger(passenger);
        }

        class PassengerManager
        {
        
            private static readonly QueuePool<PassengerNode> PassengerPool = 
                new QueuePool<PassengerNode>(Resources.Load<GameObject>("prefabs/Passenger"), new GameObject("passengers").transform);


            public static PassengerNode CreatePassenger()
            {
                PassengerNode node = PassengerPool.GetInstance();
                return node;
            }

            public static void ResetPassenger(PassengerNode passenger)
            {
                PassengerPool.ResetInstance(passenger);
            }
        
        }
    }
    

}